package com.googlecode.flair
{
	import com.googlecode.flair.builder.OptionsFactory;
	import com.googlecode.flair.editors.*;
	
	import flash.utils.Dictionary;
	import flash.utils.getQualifiedClassName;
	
	import mx.collections.ArrayCollection;
	import mx.containers.Form;
	import mx.containers.FormItem;
	
	/**
	 * 
	 * @author ccPascu
	 * 
	 */
	public class StylesEditorGenerator
	{
		
		public var flexStyles : XML = null;
		public var flexComponents : XML = null;
		private var styleEditors : Dictionary = new Dictionary();

		
		public function createStyleEditor(flairComponent : IFlairComponent) : Form 
		{
			
			var editorForm : Form = null;
			var component : Object = flairComponent.component;
			var componentClassName : String = getQualifiedClassName(component);
			if (styleEditors[componentClassName] is Form) {
				editorForm = styleEditors[componentClassName] as Form;
				var editors : Array = editorForm.getChildren();
				for each (var aEditor : IFlairEditor in editors) {
					aEditor.component = flairComponent;
				}
				return editorForm;
			} else {
				editorForm = new Form();
				editorForm.percentHeight = 100;
				editorForm.percentWidth = 100;
				styleEditors[componentClassName] = editorForm;
			}
			
			var className : String = getQualifiedClassName(component);
			var componentXml : XML = flexComponents.component.(@name==className)[0];
			if (!componentXml) {
				return null;
			}
			var inheritedStyles : String = componentXml.styles.inherited.text().toString();
			var styleNames : Array = inheritedStyles.split(" ");
			var componentStyles : Dictionary = new Dictionary();
			
			var specificStyles : String = componentXml.styles.specific.text().toString();
			styleNames = styleNames.concat(specificStyles.split(" "));
			styleNames.sort();
			var groups : Object = groupStyleNames(styleNames);
			for each (var styleName : String in styleNames) {
				var style : XMLList = flexStyles.styles.style.(@name==styleName);
				if (style && style.length() == 1) {
					putStyleEditor(style[0], editorForm, flairComponent);
					//componentStyles[styleName] = style[0];
				}
			}
			return editorForm;
		}
		
		
		private function groupStyleNames(styleNames : Array) : Object {
			while (styleNames.length > 0) {
				var styleName : String = styleNames[0];
				for each (var other : String in styleNames) {
					
				}
			}
			return null;
		}
		
		private function putStyleEditor (style : XML, editorForm : Form, flairComponent :  IFlairComponent) : void
		{
			var name : String = style.@name;
			if (style.@type == "Function"
				|| (name == "paddingBottom" || name == "paddingRight" || name == "paddingLeft")
				|| (name == "bottom" || name == "right" || name == "left")
				|| (name == "borderThicknessBottom" || name == "borderThicknessRight" || name == "borderThicknessLeft")
				|| name.indexOf("StyleName") > -1 /*No support for stylenames*/) {
				return;
			}
			var editor : IFlairEditor = createEditor(style);
			if (!editor.property) {
				editor.property = name;
			}
			if (!FormItem(editor).label) {
				FormItem(editor).label = editor.property.replace(/([A-Z])/, " $1");
				FormItem(editor).label = FormItem(editor).label.charAt(0).toUpperCase() + FormItem(editor).label.substr(1);
			}
			FormItem(editor).toolTip = style.documentation.text().toString();
			editor.component = flairComponent;
			editorForm.addChild(FormItem(editor));
		}
		
		
		public function getAllStyles() : String
		{
			var styles : XMLList = flexComponents.*.styles.style;
			var eachStyle : Object = new Object();
			for each (var style : XML in styles) {
				eachStyle[style.@name] = style;
			}
			var text : String = "";
			for (var name : String in eachStyle) {
				text += (eachStyle[name] as XML).toXMLString() + "\n";
			}
			return text;
		}
		
		private function createEditor(style : XML) : IFlairEditor
		{
			var editor : IFlairEditor = null;
			var name : String = style.@name;
			
			var type : String = style.@type;
			
			var format : String = style.@format; 
			var enumeration : String = style.@enumeration;
			if (name == "paddingTop") {
				editor = createPaddingEditor(style);
			} else if (name == "top") {
				editor = createMarginEditor(style);
			} else if (name == "borderThicknessTop") {
				editor = createBorderThicknessEditor(style);
			} else if (name == "fontFamily") {
				editor = new FontPicker();
			} else if (name == "fontSize") {
				editor = new FontSizePicker();
			} else if ( enumeration != "") {
				editor = createChoiceEditor(style);
			} else if (type == "Number") {
				editor = createNumberEditor(style);
			} else if (type == "String") {
				editor = createStringEditor(style);
			} else if (type == "Boolean") {
				editor = createBooleanEditor(style);
			} else if (type == "Array") {
				editor = createArrayEditor(style);
			} else if (type == "uint" && format == "Color") {
				editor = createColorEditor(style);
			} else if (type == "Class" && name.indexOf("Skin") > -1) {
				//editor = createSkinEditor(style);
			} else if (type == "Class" && (name.indexOf("Icon") > -1 || name == "icon") ) {
				editor = createIconEditor(style);
			}
			
			if (editor == null) {
				editor = new TextEditor();
			}
			return editor;
		}
		
		private function createNumberEditor(style : XML) : IFlairEditor {
			var editor : Slider = new Slider();
			editor.minimum = 0;
			editor.step = 1;
			if (String(style.@name).indexOf("borderThickness") > -1) {
				editor.maximum = 30;
			} else if (String(style.@name) == "cornerRadius"){				
				editor.maximum = 28;
			} else if (String(style.@name).indexOf("Alpha") > -1) {
				editor.step = 0.01;
				editor.maximum = 1;
			} else {
				editor.maximum = 30;
			}
			return editor;
		}
		
		
		
		private function createChoiceEditor(style : XML) : IFlairEditor {
			var editor : IFlairEditor = null;
			var enumeration : String = String(style.@enumeration);
			if (enumeration == "left,center,right") {
				editor = new DirectionEditor();
				DirectionEditor(editor).directions = OptionsFactory.instance.horizontalDirections;
				DirectionEditor(editor).options = OptionsFactory.instance.horizontalAlignOptions;
			} else if (enumeration == "bottom,middle,top") {
				editor = new DirectionEditor();
				DirectionEditor(editor).directions = OptionsFactory.instance.verticalDirections;
				DirectionEditor(editor).options = OptionsFactory.instance.verticalAlignOptions;
			} else {
				editor = new ChoiceEditor();
				ChoiceEditor(editor).options = new ArrayCollection(String(enumeration).split(","));
			}
			return editor;
		}
		
		private function createStringEditor(style : XML) : IFlairEditor {
			var editor : IFlairEditor = new TextEditor();
			return editor;
		}
		
		private function createBooleanEditor(style : XML) : IFlairEditor {
			var editor : IFlairEditor = new BooleanEditor();
			return editor;
		}
		
		private function createArrayEditor(style : XML) : IFlairEditor {
			var editor : IFlairEditor = null;
			if (style.@name == "fillAlphas") {
				editor = new QuatroSlider();
				QuatroSlider(editor).minimum = 0;
				QuatroSlider(editor).maximum = 1;
				QuatroSlider(editor).step = 0.01;
			} else if (style.@name == "fillColors") {
				editor = new QuatroColorPicker();
			} else if (style.@arrayType == "uint" && style.@format == "Color") {
				editor = new DoubleColorPicker();
			} else if (style.@arrayType == "Number") {
				editor = new DoubleSlider();
				if (String(style.@name).indexOf("Alpha") > -1) {
					DoubleSlider(editor).minimum = 0;
					DoubleSlider(editor).maximum = 1;
					DoubleSlider(editor).step = 0.01;
				}
			}
			return editor;
		}
		
		private function createMarginEditor (style : XML) : IFlairEditor
		{
			var editor : QuatroSlider = new QuatroSlider();
			editor.properties = ['top', 'right', 'bottom', 'left'];
			editor.minimum = 0;
			editor.maximum = 30;
			editor.step = 1;
			editor.label = "Margins";
			return editor;
		}
		
		private function createPaddingEditor (style : XML) : IFlairEditor
		{
			var editor : QuatroSlider = new QuatroSlider();
			editor.properties = ['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft'];
			editor.minimum = 0;
			editor.maximum = 30;
			editor.step = 1;
			editor.label = "Padding";
			return editor;
		}
		
		private function createBorderThicknessEditor (style : XML) : IFlairEditor
		{
			var editor : QuatroSlider = new QuatroSlider();
			editor.properties = ['borderThicknessTop', 'borderThicknessRight', 'borderThicknessBottom', 'borderThicknessBottom'];
			editor.minimum = 0;
			editor.maximum = 30;
			editor.step = 1;
			editor.label = "Border Thickness";
			return editor;
		}
		
		private function createColorEditor(style : XML) : IFlairEditor {
			var editor : IFlairEditor = new ColorPicker();
			return editor;
		}
		
		private function createSkinEditor(style : XML) : IFlairEditor {
			var editor : IFlairEditor = new TextEditor();
			return editor;
		}
		
		private function createIconEditor(style : XML) : IFlairEditor {
			var editor : IFlairEditor = new IconEditor();
			return editor;
		}
	}
}